package com.eternal.advance.model;

import androidx.databinding.Observable;
import androidx.databinding.ObservableBoolean;
import androidx.databinding.ObservableField;
import androidx.databinding.ObservableInt;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;

import com.eternal.advance.AdvanceFragment;
import com.eternal.advance.R;
import com.eternal.base.concat.DeviceModel;
import com.eternal.base.database.entity.Notification;
import com.eternal.base.global.BluetoothKey;
import com.eternal.base.protocol.ProtocolTransformer;
import com.eternal.base.utils.GuQiangUtil;
import com.eternal.framework.binding.command.BindingAction;
import com.eternal.framework.binding.command.BindingCommand;
import com.eternal.framework.bus.Messenger;
import com.eternal.widget.ColorSpan;
import com.google.common.primitives.UnsignedBytes;

/**
 * Created by Administrator
 * On 2020/5/7
 * Description:
 *
 * @author Administrator
 */
public class ItemModel {
    private static final int[] COLORS = new int[]{0xff128bec, 0xff1da9f1, 0xff29c9f7};
    private static ColorSpan span;
    public Notification model;
    public ObservableInt typeRes = new ObservableInt();
    public ObservableField<Spannable> title = new ObservableField<>();
    public ObservableField<String> info = new ObservableField<>();
    public ObservableBoolean open = new ObservableBoolean();
    public Observable.OnPropertyChangedCallback callback;


    public BindingCommand<Void> onEdit = new BindingCommand<Void>(new BindingAction() {
        @Override
        public void call() {
            Messenger.getDefault().send(ItemModel.this, AdvanceModel.ITEM_EDIT);
        }
    });

    public BindingCommand<Void> onDelete = new BindingCommand<Void>(new BindingAction() {
        @Override
        public void call() {
            Messenger.getDefault().send(ItemModel.this, AdvanceFragment.ITEM_DELETE);
        }
    });

    ItemModel(Notification notification, final DeviceModel info) {
        model = notification;
        span = new ColorSpan(COLORS);
        final SpannableString name = new SpannableString(notification.name);
        title.set(name);
        switch (notification.type) {
            case BluetoothKey.AUTOMATION:
                typeRes.set(R.drawable.advance_type_rc_automations_selector);
                break;
            case BluetoothKey.ALARMS:
                typeRes.set(R.drawable.advance_type_rc_alarm_selector);
                break;
            default:
                typeRes.set(R.drawable.advance_type_rc_notification_selector);
        }
        changeOpen();
        open.set(notification.open);
        this.info.set(getInfo(notification, info));
        callback=new Observable.OnPropertyChangedCallback() {
            @Override
            public void onPropertyChanged(Observable sender, int propertyId) {
                model.open = open.get();
                changeOpen();
                Messenger.getDefault().send(ItemModel.this, AdvanceModel.ITEM_OPEN);
            }
        };
        open.addOnPropertyChangedCallback(callback);
    }

    public void updateInfo(DeviceModel model){
        info.set(getInfo(this.model, model));
    }

    private void changeOpen() {
        if (model.open) {
            Spannable old = title.get();
            Spannable ne = new SpannableString(old.toString());
            ne.setSpan(span, 0, ne.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            title.set(ne);
        } else {
            Spannable old = title.get();
            title.set(new SpannableString(old.toString()));
        }
    }

    void setOpen(boolean b){
        open.removeOnPropertyChangedCallback(callback);
        open.set(b);
        model.open=b;
        changeOpen();
        open.addOnPropertyChangedCallback(callback);
    }

    private String getInfo(Notification notification, DeviceModel info) {
        StringBuilder builder = new StringBuilder();
        int h, l;
        String unit;
        if (notification.type == BluetoothKey.AUTOMATION) {
            builder.append(GuQiangUtil.stringForTimeBySched(notification.start))
                    .append(" to ")
                    .append(GuQiangUtil.stringForTimeBySched(notification.end));
            switch (notification.model) {
                case 0x1:
                    builder.append("\nON");
                    break;
                case 0x2:
                    builder.append("\nOFF");
                    break;
                case 0x3:
                    builder.append(String.format("\nCYCLE (ON %s, OFF %s)",
                            GuQiangUtil.stringForTimeByCycleSpace(notification.cycleOn),
                            GuQiangUtil.stringForTimeByCycleSpace(notification.cycleOff)));
                    break;
                default:
                    if (notification.tmpHum != 0) {
                        builder.append("\n");
                        if (info.isDegree) {
                            h = notification.hTmpC;
                            l = notification.lTmpC;
                            unit = "℃";
                        } else {
                            h = UnsignedBytes.toInt(notification.hTmpF);
                            l = UnsignedBytes.toInt(notification.lTmpF);
                            unit = "℉";
                        }
                        initTmpHum(builder, unit, h, l, notification.hHum, notification.lHum, notification.tmpHum);
                    }
            }
        } else {
            if (ProtocolTransformer.paramModel(notification.model) && notification.tmpHum != 0) {
                builder.append("\n");
                if (info.isDegree) {
                    h = notification.hTmpC;
                    l = notification.lTmpC;
                    unit = "℃";
                } else {
                    h = UnsignedBytes.toInt(notification.hTmpF);
                    l = UnsignedBytes.toInt(notification.lTmpF);
                    unit = "℉";
                }
                initTmpHum(builder, unit, h, l, notification.hHum, notification.lHum, notification.tmpHum);
            }

            if (ProtocolTransformer.autoModel(notification.model)) {
                byte tmpHum=ProtocolTransformer.getTmpSwitch(info);
                builder.append("\nAUTO");
                if(tmpHum!=0){
                    int orignDegree = AdvanceModel.orignDegree;
                    if (info.isDegree) {
                        if(orignDegree==2){
                            h = UnsignedBytes.toInt(info.autoHighTmp);
                            l = UnsignedBytes.toInt(info.autoLowTmp);
                            h = (h - 32 ) * 5 / 9+((h - 32 ) * 5 % 9>4?1:0);
                            l = (l - 32 ) * 5 / 9+((l - 32 ) * 5 % 9>4?1:0);
                            AdvanceModel.isSetChange = true;
//                            KLog.i("==== C ====orignDegree==2=====");
                        }else{
                            h = info.autoHighTmp;
                            l = info.autoLowTmp;
//                            KLog.i("==== C =========");
                        }
                        unit = "℃";
                    } else {
                        if(orignDegree==1){
                            h = info.autoHighTmp;
                            l = info.autoLowTmp;
                            h = (h * 9 / 5) + 32 + ((h * 9 % 5)>2?1:0);
                            l = (l * 9 / 5) + 32 + ((l * 9 % 5)>2?1:0);
                            AdvanceModel.isSetChange = true;
//                            KLog.i("===== F ===orignDegree==1=====");
                        }else{
                            h = UnsignedBytes.toInt(info.autoHighTmp);
                            l = UnsignedBytes.toInt(info.autoLowTmp);
//                            KLog.i("==== F =========");
                        }
                        unit = "℉";
                    }
//                    KLog.i("=======h =="+h  +",  l  == "+l);
                    builder.append(" (");
                    initTmpHum(builder, unit,h,l, info.autoHighHum, info.autoLowHum, tmpHum);
                    builder.append(")");
                }
            }

            if (ProtocolTransformer.onModel(notification.model)) {
                builder.append(String.format("\nTIMER TO ON (%s)",
                        GuQiangUtil.stringForTimeByCycleSpace(info.timeOn)));
            }

            if (ProtocolTransformer.offModel(notification.model)) {
                builder.append(String.format("\nTIMER TO OFF (%s)",
                        GuQiangUtil.stringForTimeByCycleSpace(info.timeOff)));
            }

            if (ProtocolTransformer.cycleModel(notification.model)) {
                builder.append(String.format("\nCYCLE (ON %s, OFF %s)",
                        GuQiangUtil.stringForTimeByCycleSpace(info.cycleOn),
                        GuQiangUtil.stringForTimeByCycleSpace(info.cycleOff)));
            }

            if (ProtocolTransformer.scheduleModel(notification.model)) {
                builder.append(String.format("\nSCHEDULE (%s to %s)",
                        GuQiangUtil.stringForTimeByAmPm(info.schedOn),
                        GuQiangUtil.stringForTimeByAmPm(info.schedOff)));
            }
            if (builder.length() != 0) {
                builder.deleteCharAt(0);
            }
        }
        return builder.toString();
    }

    private void initTmpHum(StringBuilder builder, String unit, int h, int l, byte hHum, byte lHum, int tmpHum) {
        if ((tmpHum & 8) != 0) {
            builder.append("H ")
                    .append(h)
                    .append(unit)
                    .append(", ");
        }
        if ((tmpHum & 4) != 0) {
            builder.append("L ")
                    .append(l)
                    .append(unit)
                    .append(", ");
        }
        if ((tmpHum & 2) != 0) {
            builder.append("H ")
                    .append(hHum)
                    .append("%, ");
        }
        if ((tmpHum & 1) != 0) {
            builder.append("L ")
                    .append(lHum)
                    .append("%, ");
        }
        if(builder.length()>2){
            builder.setLength(builder.length() - 2);
        }else{
            builder.setLength(0);
        }
    }

    Notification getNotification() {
        return model;
    }
}